package com.zenithmind.document.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.result.Result;
import com.zenithmind.document.pojo.dto.DocumentCreateDTO;
import com.zenithmind.document.pojo.dto.DocumentUpdateDTO;
import com.zenithmind.document.pojo.dto.DocumentUploadDTO;
import com.zenithmind.document.pojo.query.DocumentQueryDTO;
import com.zenithmind.document.pojo.vo.DocumentDetailVO;
import com.zenithmind.document.pojo.vo.DocumentVO;
import com.zenithmind.document.service.DocumentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import java.util.List;

/**
 * 文档兼容性控制器
 * 遵循开闭原则：保持向后兼容性，不破坏现有API
 * 遵循单一职责原则：专注于API兼容性维护
 * 
 * 此控制器维护原有的API路径，确保前端应用不受影响
 * 内部委托给新的专门控制器处理具体业务逻辑
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@RestController
@RequestMapping("/api/zenithMind/document")
@RequiredArgsConstructor
@Validated
@Tag(name = "文档兼容性接口", description = "保持向后兼容的文档管理接口")
public class DocumentCompatibilityController {

    private final DocumentService documentService;

    // ========== 基础文档管理接口（兼容原有路径） ==========

    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @Operation(summary = "上传文档", description = "上传文档文件（兼容接口）")
    public Result<DocumentVO> uploadDocument(@Valid DocumentUploadDTO uploadDTO) {
        log.info("兼容接口：上传文档");
        return Result.success(documentService.uploadDocument(uploadDTO));
    }

    @PostMapping
    @Operation(summary = "创建文档", description = "创建新文档（兼容接口）")
    public Result<DocumentVO> createDocument(@Valid @RequestBody DocumentCreateDTO createDTO) {
        log.info("兼容接口：创建文档");
        return Result.success(documentService.createDocument(createDTO));
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新文档", description = "更新文档信息（兼容接口）")
    public Result<Boolean> updateDocument(
            @PathVariable @NotBlank String id,
            @Valid @RequestBody DocumentUpdateDTO updateDTO) {
        log.info("兼容接口：更新文档 id={}", id);
        return Result.success(documentService.updateDocument(id, updateDTO));
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除文档", description = "删除文档（兼容接口）")
    public Result<Boolean> deleteDocument(@PathVariable @NotBlank String id) {
        log.info("兼容接口：删除文档 id={}", id);
        return Result.success(documentService.deleteDocument(id));
    }

    @GetMapping("/page")
    @Operation(summary = "分页查询文档", description = "分页查询文档列表（兼容接口）")
    public Result<IPage<DocumentVO>> getDocumentPage(@Valid DocumentQueryDTO queryDTO) {
        log.info("兼容接口：分页查询文档");
        return Result.success(documentService.getDocumentPage(queryDTO));
    }

    @GetMapping("/{id}")
    @Operation(summary = "获取文档详情", description = "获取文档详细信息（兼容接口）")
    public Result<DocumentDetailVO> getDocumentDetail(@PathVariable @NotBlank String id) {
        log.info("兼容接口：获取文档详情 id={}", id);
        String userId = UserContext.getUserId();
        return Result.success(documentService.getDocumentDetail(id, userId));
    }

    // ========== 搜索相关接口（兼容原有路径） ==========

    @GetMapping("/search")
    @Operation(summary = "搜索文档", description = "根据关键词搜索文档（兼容接口）")
    public Result<List<DocumentVO>> searchDocuments(
            @RequestParam @NotBlank String keyword,
            @RequestParam(required = false, defaultValue = "20") Integer limit) {
        log.info("兼容接口：搜索文档 keyword={}", keyword);
        String userId = UserContext.getUserId();
        return Result.success(documentService.searchDocuments(keyword, userId, limit));
    }

    @GetMapping("/my")
    @Operation(summary = "获取我的文档", description = "获取当前用户的文档（兼容接口）")
    public Result<List<DocumentVO>> getMyDocuments(
            @RequestParam(required = false, defaultValue = "20") Integer limit) {
        log.info("兼容接口：获取我的文档");
        String userId = UserContext.getUserId();
        return Result.success(documentService.getUserDocuments(userId, limit));
    }

    @GetMapping("/recent")
    @Operation(summary = "获取最近文档", description = "获取最近访问的文档（兼容接口）")
    public Result<List<DocumentVO>> getRecentDocuments(
            @RequestParam(required = false, defaultValue = "10") Integer limit) {
        log.info("兼容接口：获取最近文档");
        String userId = UserContext.getUserId();
        return Result.success(documentService.getRecentDocuments(userId, limit));
    }

    @GetMapping("/favorites")
    @Operation(summary = "获取收藏文档", description = "获取收藏的文档（兼容接口）")
    public Result<List<DocumentVO>> getFavoriteDocuments(
            @RequestParam(required = false, defaultValue = "20") Integer limit) {
        log.info("兼容接口：获取收藏文档");
        String userId = UserContext.getUserId();
        return Result.success(documentService.getFavoriteDocuments(userId, limit));
    }

    @GetMapping("/hot")
    @Operation(summary = "获取热门文档", description = "获取热门文档（兼容接口）")
    public Result<List<DocumentVO>> getHotDocuments(
            @RequestParam(required = false, defaultValue = "10") Integer limit) {
        log.info("兼容接口：获取热门文档");
        return Result.success(documentService.getHotDocuments(limit));
    }

    @GetMapping("/latest")
    @Operation(summary = "获取最新文档", description = "获取最新文档（兼容接口）")
    public Result<List<DocumentVO>> getLatestDocuments(
            @RequestParam(required = false, defaultValue = "10") Integer limit) {
        log.info("兼容接口：获取最新文档");
        String userId = UserContext.getUserId();
        return Result.success(documentService.getLatestDocuments(userId, limit));
    }

    // ========== 收藏相关接口（兼容原有路径） ==========

    @PostMapping("/{id}/favorite")
    @Operation(summary = "收藏文档", description = "收藏指定文档（兼容接口）")
    public Result<Boolean> favoriteDocument(@PathVariable @NotBlank String id) {
        log.info("兼容接口：收藏文档 id={}", id);
        String userId = UserContext.getUserId();
        return Result.success(documentService.favoriteDocument(id, userId));
    }

    @PostMapping("/{id}/unfavorite")
    @Operation(summary = "取消收藏", description = "取消收藏文档（兼容接口）")
    public Result<Boolean> unfavoriteDocument(@PathVariable @NotBlank String id) {
        log.info("兼容接口：取消收藏文档 id={}", id);
        String userId = UserContext.getUserId();
        return Result.success(documentService.unfavoriteDocument(id, userId));
    }

    // ========== 版本相关接口（兼容原有路径） ==========

    @GetMapping("/{id}/versions")
    @Operation(summary = "获取文档版本", description = "获取文档版本历史（兼容接口）")
    public Result<List<DocumentVO>> getDocumentVersions(@PathVariable @NotBlank String id) {
        log.info("兼容接口：获取文档版本 id={}", id);
        return Result.success(documentService.getDocumentVersions(id));
    }

    @PostMapping("/{documentId}/versions/{versionId}/restore")
    @Operation(summary = "恢复文档版本", description = "恢复到指定版本（兼容接口）")
    public Result<Boolean> restoreDocumentVersion(
            @PathVariable @NotBlank String documentId,
            @PathVariable @NotBlank String versionId) {
        log.info("兼容接口：恢复文档版本 documentId={}, versionId={}", documentId, versionId);
        String userId = UserContext.getUserId();
        return Result.success(documentService.restoreDocumentVersion(documentId, versionId, userId));
    }

    // ========== 模板相关接口（兼容原有路径） ==========

    @GetMapping("/templates")
    @Operation(summary = "获取文档模板", description = "获取文档模板列表（兼容接口）")
    public Result<List<Object>> getDocumentTemplates() {
        log.info("兼容接口：获取文档模板");

        try {
            List<Object> templates = getAvailableTemplates();
            return Result.success(templates);
        } catch (Exception e) {
            log.error("获取文档模板失败", e);
            return Result.fail("获取文档模板失败: " + e.getMessage());
        }
    }

    @PostMapping("/templates/{templateId}/create")
    @Operation(summary = "使用模板创建文档", description = "使用模板创建新文档（兼容接口）")
    public Result<DocumentVO> createDocumentFromTemplate(
            @PathVariable @NotBlank String templateId,
            @RequestBody Object data) {
        log.info("兼容接口：使用模板创建文档 templateId={}", templateId);

        try {
            String userId = UserContext.getUserId();
            DocumentVO result = createDocumentFromTemplateData(templateId, data, userId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("使用模板创建文档失败: templateId={}", templateId, e);
            return Result.fail("使用模板创建文档失败: " + e.getMessage());
        }
    }

    @PostMapping("/{id}/save-as-template")
    @Operation(summary = "保存为模板", description = "将文档保存为模板（兼容接口）")
    public Result<Boolean> saveDocumentAsTemplate(
            @PathVariable @NotBlank String id,
            @RequestBody Object data) {
        log.info("兼容接口：保存为模板 id={}", id);

        try {
            String userId = UserContext.getUserId();
            Boolean result = saveDocumentAsTemplateData(id, data, userId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("保存为模板失败: id={}", id, e);
            return Result.fail("保存为模板失败: " + e.getMessage());
        }
    }

    // ========== 其他功能接口（兼容原有路径） ==========

    @GetMapping("/{id}/download")
    @Operation(summary = "下载文档", description = "下载文档文件（兼容接口）")
    public Result<byte[]> downloadDocument(@PathVariable @NotBlank String id) {
        log.info("兼容接口：下载文档 id={}", id);
        String userId = UserContext.getUserId();
        return Result.success(documentService.downloadDocument(id, userId));
    }

    @GetMapping("/{id}/preview")
    @Operation(summary = "预览文档", description = "预览文档内容（兼容接口）")
    public Result<String> previewDocument(@PathVariable @NotBlank String id) {
        log.info("兼容接口：预览文档 id={}", id);
        String userId = UserContext.getUserId();
        return Result.success(documentService.previewDocument(id, userId));
    }

    @PostMapping("/{id}/convert")
    @Operation(summary = "转换文档格式", description = "转换文档格式（兼容接口）")
    public Result<String> convertDocument(
            @PathVariable @NotBlank String id,
            @RequestParam @NotBlank String targetFormat) {
        log.info("兼容接口：转换文档格式 id={}, targetFormat={}", id, targetFormat);
        String userId = UserContext.getUserId();
        return Result.success(documentService.convertDocument(id, targetFormat, userId));
    }

    @DeleteMapping("/batch")
    @Operation(summary = "批量删除文档", description = "批量删除文档（兼容接口）")
    public Result<Boolean> batchDeleteDocuments(@RequestBody @NotEmpty List<String> ids) {
        log.info("兼容接口：批量删除文档 ids={}", ids);
        return Result.success(documentService.batchDeleteDocuments(ids));
    }

    @PostMapping("/move")
    @Operation(summary = "移动文档", description = "移动文档到指定分类（兼容接口）")
    public Result<Boolean> moveDocuments(
            @RequestBody @NotEmpty List<String> documentIds,
            @RequestParam @NotBlank String categoryId) {
        log.info("兼容接口：移动文档 documentIds={}, categoryId={}", documentIds, categoryId);
        return Result.success(documentService.moveDocuments(documentIds, categoryId));
    }

    // ========== 辅助方法 ==========

    /**
     * 获取可用模板列表
     */
    private List<Object> getAvailableTemplates() {
        List<Object> templates = new java.util.ArrayList<>();

        // 模拟模板数据
        java.util.Map<String, Object> template1 = new java.util.HashMap<>();
        template1.put("id", "template_1");
        template1.put("name", "技术文档模板");
        template1.put("description", "用于创建技术文档的标准模板");
        template1.put("category", "技术");
        template1.put("previewUrl", "/templates/preview/template_1.png");
        templates.add(template1);

        java.util.Map<String, Object> template2 = new java.util.HashMap<>();
        template2.put("id", "template_2");
        template2.put("name", "产品说明模板");
        template2.put("description", "用于创建产品说明文档的模板");
        template2.put("category", "产品");
        template2.put("previewUrl", "/templates/preview/template_2.png");
        templates.add(template2);

        java.util.Map<String, Object> template3 = new java.util.HashMap<>();
        template3.put("id", "template_3");
        template3.put("name", "会议纪要模板");
        template3.put("description", "用于记录会议内容的标准模板");
        template3.put("category", "会议");
        template3.put("previewUrl", "/templates/preview/template_3.png");
        templates.add(template3);

        return templates;
    }

    /**
     * 使用模板创建文档
     */
    private DocumentVO createDocumentFromTemplateData(String templateId, Object data, String userId) {
        // 模拟从模板创建文档
        DocumentCreateDTO createDTO = new DocumentCreateDTO();
        createDTO.setTitle("基于模板创建的文档 - " + templateId);
        createDTO.setContent(generateTemplateContent(templateId));
        createDTO.setCategoryId("default");
        // createDTO.setCreatorId(userId); // 创建时会自动设置创建者

        // 调用文档服务创建文档
        return documentService.createDocument(createDTO);
    }

    /**
     * 保存文档为模板
     */
    private Boolean saveDocumentAsTemplateData(String documentId, Object data, String userId) {
        // 模拟保存为模板的逻辑
        log.info("保存文档为模板: documentId={}, userId={}", documentId, userId);

        // 获取文档信息
        DocumentVO document = documentService.getDocumentDetail(documentId, userId);
        if (document == null) {
            throw new RuntimeException("文档不存在");
        }

        // 模拟保存模板逻辑
        // 实际实现中应该：
        // 1. 提取文档内容和格式
        // 2. 创建模板记录
        // 3. 保存模板文件

        return true;
    }

    /**
     * 生成模板内容
     */
    private String generateTemplateContent(String templateId) {
        switch (templateId) {
            case "template_1":
                return "# 技术文档\n\n## 概述\n\n## 技术架构\n\n## 实现细节\n\n## 总结";
            case "template_2":
                return "# 产品说明\n\n## 产品概述\n\n## 功能特性\n\n## 使用方法\n\n## 注意事项";
            case "template_3":
                return "# 会议纪要\n\n**会议时间：**\n\n**参会人员：**\n\n## 会议议题\n\n## 讨论内容\n\n## 决议事项\n\n## 后续行动";
            default:
                return "# 文档标题\n\n## 内容章节\n\n文档内容...";
        }
    }
}
